package com.report.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.SearchResult;

import cn.zhxu.bs.operator.Contain;
import cn.zhxu.bs.operator.Equal;
import cn.zhxu.bs.util.MapUtils;
import com.report.dto.WebDownloadProperties;
import com.report.dto.request.InsightReq;
import com.report.dto.request.ReportFileReq;
import com.report.dto.response.*;
import com.report.entity.*;
import com.report.mapper.ReportFileMapper;

import com.report.service.*;
import com.report.utils.DownloadFileUtils;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.exception.ResultException;
import com.zmh.framework.oss.OssConfigure;
import com.zmh.framework.util.Base64ToMultipartFile;
import lombok.AllArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author summer
 * @since 2024/06/25 14:54:57
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class ReportFileServiceImpl extends ServiceImpl<ReportFileMapper, ReportFile> implements IReportFileService {

    private final OssConfigure ossConfigure;

    private final ReportFileTagService tagService;

    private final SpecialReportService specialReportService;

    @Override
    public void saveReportFile(ReportFileReq reportFileReq) {
        ReportFile reportFile = Convert.convert(ReportFile.class, reportFileReq);
        if (reportFileReq.getShowImage()) {
            MultipartFile multipartFile = Base64ToMultipartFile.base64ToMultipart(reportFileReq.getBase64());
            String filePath = ossConfigure.getAccessUrl() + ossConfigure.uploadFile(multipartFile);
            reportFile.setImage(filePath);
        }

        this.saveOrUpdate(reportFile);

        tagService.saveSpecialTagList(reportFileReq.getTagName(),reportFile.getId());
        //TODO 专题标签

        specialReportService.saveSpecialReport(reportFile.getId(),reportFileReq.getReportIds());


        //TODO 专题关联报告

    }

    private final BeanSearcher beanSearcher;

    @Override
    public Page<SysReportFileRes> lists(ReportFileReq reportFileReq) {
        Page<SysReportFileRes> page = new Page<>(reportFileReq.getPageNum(), reportFileReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(reportFileReq.getPageNum() - 1, reportFileReq.getPageSize())
                .field(SysReportFileRes::getName, reportFileReq.getName()).op(Contain.class)
                .field(SysReportFileRes::getTagName, reportFileReq.getTagName()).op(Contain.class)
                .field(SysReportFileRes::getDeleted, Constants.ZERO).op(Equal.class)
                 .build();
        SearchResult<SysReportFileRes> search = beanSearcher.search(SysReportFileRes.class, build);
        page.setTotal(search.getTotalCount().longValue());
        page.setRecords(search.getDataList());
        return page;
    }

    private final ICollectService collectService;


    @Override
    public Page<ReportFileRes> wechatSpecialList(ReportFileReq reportFileReq) {
        Page<ReportFileRes> page = new Page<>(reportFileReq.getPageNum(), reportFileReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(reportFileReq.getPageNum() - 1, reportFileReq.getPageSize())
                .field(ReportFileRes::getName, reportFileReq.getName()).op(Contain.class)
                .field(ReportFileRes::getTagName, reportFileReq.getTagName()).op(Contain.class)
                .field(ReportFileRes::getDeleted, Constants.ZERO).op(Equal.class)
                .build();
        SearchResult<ReportFileRes> search = beanSearcher.search(ReportFileRes.class, build);
        page.setTotal(search.getTotalCount().longValue());
        List<ReportFileRes> dataList = search.getDataList();
        page.setRecords(dataList);
        //保存搜索条件信息
        if(StrUtil.isNotEmpty(reportFileReq.getName())){
            Search search1=new Search();
            search1.setName(reportFileReq.getName());
            if(StpUtil.isLogin()){
                search1.setMemberId(StpUtil.getLoginIdAsInt());
            }
            searchService.saveSearch(search1);
        }
        return page;
    }

    private final ISearchService searchService;

    @Override
    public SysReportFileRes findById(Integer id) {
        Map<String, Object> build = MapUtils.builder().field(SysReportFileRes::getId, id).op(Equal.class).build();
        return beanSearcher.searchFirst(SysReportFileRes.class, build);
    }

    @Override
    public Page<SpecialRes> specialList(Integer pageNum, Integer pageSize) {
        Page<SpecialRes> page = new Page<>(pageNum, pageSize);
        return this.baseMapper.specialList(page);
    }

    @Override
    public SpecialRes findSpecialById(Integer id) {
        return this.baseMapper.findSpecialById(id);
    }

    @Override
    public Page<ReportRes> findSpecialAndReportList(InsightReq insightReq) {
        Page<ReportRes> page = new Page<>(insightReq.getPageNum(), insightReq.getPageSize());
        return this.baseMapper.findReportList(page, insightReq.getId());
    }

   private final WebDownloadProperties webDownloadProperties;

    private final IMemberService memberService;

    private final DownloadReportService downloadReportService;

    private final DownloadFileUtils downloadFileUtils;


    @Override
    public List<ReportRes> vipReport(Integer id) {
        MemberRes memberRes = memberService.memberInfo();
        WechatMiniReportFileRes specialListById = findSpecialListById(id);
        List<ReportRes> reportResList = specialListById.getReportResList();
        Integer downloadMonth = memberRes.getDownloadMonth();
        Integer downloadDay = memberRes.getDownloadDay();
        if(reportResList.size()>downloadDay || reportResList.size()>downloadMonth){
            throw new ResultException("专题合集下载量超过限制");
        }
        return reportResList;
    }

    @Override
    public void downloadVipReportFile(Integer id, HttpServletResponse response) {
         MemberRes memberRes = memberService.memberInfo();
        WechatMiniReportFileRes specialListById = findSpecialListById(id);
        List<ReportRes> reportResList = specialListById.getReportResList();
        Integer downloadMonth = memberRes.getDownloadMonth();
        Integer downloadDay = memberRes.getDownloadDay();
        if(reportResList.size()>downloadDay || reportResList.size()>downloadMonth){
            throw new ResultException("专题合集下载量超过限制");
        }


        reportResList.forEach(reportRes -> {
            String path = reportRes.getPath();
            String fileName = StrUtil.subAfter(path, ossConfigure.getAccessUrl(), true);
            downloadFileUtils.downloadVipPdf(fileName,reportRes.getFileName());
        });

        downloadFileUtils.downloadZip(response);
            reportResList.forEach(reportRes -> {
                DownloadReport downloadReport = new DownloadReport();
                downloadReport.setReportId(reportRes.getId());
                downloadReport.setMemberId(StpUtil.getLoginIdAsInt());
                downloadReportService.save(downloadReport);
                downloadFileUtils.removeFile(reportRes.getFileName());
            });




    }


    @Override
    public WechatMiniReportFileRes findSpecialListById(Integer id) {

        return this.baseMapper.findSpecialListById(id);
    }


}

